
/* Private typedef -----------------------------------------------------------*/
extern u8 USART1_TX_BUF[];	//定义在usart.c
extern u8 USART1_RX_BUF[];
extern u8 USART3_TX_BUF[];	//定义在usart3.c
extern u8 USART2_RX_BUF[];
extern u8 USART3_RX_BUF[];
extern u8 USART1_TX_Count;	//USART1 发送字节计数
extern u8 USART1_RX_Count;	//USART1 接收字节计数
extern u8 USART3_TX_Count;	//USART1 发送字节计数
extern u8 USART3_RX_Count;	//USART1 接收字节计数
extern u8 USART1_RX_flag;		//USART1 接收到一帧有效数据的标志
extern u8 USART3_RX_flag;		//USART3 接收到一帧有效数据的标志
extern u16 USART3_RX_STA; //时间匹配法的状态变量  来表示接收到的数据状态和接收数据的长度
extern u16 USART1_RX_STA; //时间匹配法的状态变量  来表示接收到的数据状态和接收数据的长度



//方式1：数据回显 收到什么再发出什么--------------------------------------------
void USART1_IRQHandler(void)
{
  	u8 res = 0;
	if(USART1->SR&(1<<5)) //接收到数据
	{	
		USART1->SR &= ~(1<<5); 			 //清空接收中断 标志位
	  LED1_Blink();
	  res = USART1->DR;		
		
		USART1->DR = (u8) res;     //测试用，再发回去
		while((USART1->SR&(1<<7))==0);//【这个地方用TXE 比 TC 好，TC容易出问题】
	}
}

//方式2：帧尾匹配法 
//接收端 帧尾匹配：根据一帧数据结尾的两个字节进行匹配，比如每一帧帧尾都是0xAA 0X55
extern uint8_t USART2_RX_BUF[]; 	//USART2接收缓存区
extern uint8_t data_buff[]; 		//USART2发送缓存区
extern __IO uint8_t USART2_RX_Count;	//USART2接收计数


void USART2_IRQHandler(void)
{
	u8 i;
	if((USART2->SR&(1<<5)) !=0)   //RXNE 读数据寄存器非空 
	{
	/* Read one byte from the receive data register */
	USART2_RX_BUF[USART2_RX_Count++] = USART2->DR;		//将 R-DR寄存器数据缓存到接收缓存区
	
	/* 匹配帧尾标识符 看结束标志是否为 0xAA 0x55 */
	if(USART2_RX_BUF[USART2_RX_Count-2]==0xAA && USART2_RX_BUF[USART2_RX_Count-1]==0X55)
		{
			for(i=0;i<USART2_RX_Count;i++) 
				data_buff[i]=USART2_RX_BUF[i];
			USART2_RX_flag=1;					//完整的数据帧!!!这样在外边就可以查询这个标志位，操作缓存区数据
			data_buff[USART2_RX_Count]=0;		//加入结束符 0x00
			USART2_RX_Count=0;	//接收计数清零			
		}
	}
//	if((USART2->SR&(1<<7)) !=0)   //TXE 发送数据寄存器为空  有时候第一个字节有BUG
//	USART2->SR &= ~(1<<7);				//清零 禁止发送缓冲器空中断
	
}
// 高频查询 
	if(USART2_RX_flag==1)  //收到一帧有效数据
	{
			
		USART_StrSend(USART2,data_buff);
		USART2_RX_flag=0;
	}
//	帧尾匹配法 end


// 数据定长 帧头匹配法 0x01 0x03 2 + 23 总长25byte
//01 03 14 [00 00] [00 00] [00 00] [00 00] [00 00] [00 00] [00 00] [00 00] [FF BD] [13 87] 4E 05
void USART3_IRQHandler(void)
{
	static u8 Rx_state = 0 ,state = 0 ,buf_index=0;  //Rx_state接收标志并且标记接收状态	state接收完整的有效帧状态
  u8 res; 															// 数据中转
	if(USART3->SR&(1<<5)) 				//接收到数据
	{	
		res=USART3->DR & 0x01FF ;		//先收数据，再清标志，这样比较好
		USART3->SR &= ~(1<<5); 			 //清空接收中断 标志位	  	
		//USART2->DR=res;	//回显一下，【测试用 串口2刚好打印调试的】
		if(Rx_state==0&&res==0x01) 
		{															//判断第一帧头 		
		   Rx_state = 1;
			 USART3_RX_BUF[0]=res;			
		}	
		else if (Rx_state==1&&res==0x03)
			{ 												//收完第一帧判断第二帧
		   Rx_state=2;
			 USART3_RX_BUF[1]=res;
		  }
		else if (Rx_state==2)
			{													//接收剩余的帧数据 2+23
			USART3_RX_BUF[2+buf_index++] =res ;				
			if(buf_index==23)//长度
				{ 											//数据接收完毕						
				Rx_state = 0;		//状态清除
				buf_index = 0;
				state = 1;
				}
			}
		if(state==1)
			{			
		  receive_data((u8*)USART3_RX_BUF); // 数据解析函数
			state = 0 ;
		}    
	}
}
//数据定长 帧头匹配法 end


//时间匹配法 
/**
  ******************************************************************************
  * @function 	TIM3 10ms   配合串口1使用使用，接收数据  
  *	@ATTENTION	
  ******************************************************************************
  */
void TIM3_IRQHandler(void)
{
	u16 rlen;
 if((TIM3->SR&0x01))  //产生 更新中断
	 { 
		USART1_RX_STA |=1<<15;		 //到时间了，强制标记接收完成		 
		TIM3->SR&=~(0x01) ;			//清除标志位
		TIMx_Status(TIM3,DISABLE);	//关闭TIM3	
	 }
   if(USART1_RX_STA&0x8000)
	 {
		rlen=USART1_RX_STA&0X7FFF;	//得到本次接收到的实际数据长度
		USART1_RX_BUF[rlen]= '\0';		//添加结束符 
		//USART_StrSend(USART3,USART1_RX_BUF);  // send to UART3 回显监控数据
		//数据解析判断
		//data_reveice();//解析USART1_RX_BUF	  
		USART1_RX_STA = 0;
	 }
}


void USART1_IRQHandler(void)
{
  u8 res = 0;
	if(USART1->SR&(1<<5)) //接收到数据
	{	
		USART1->SR &= ~(1<<5); 			 //清空接收中断 标志位
		res = USART1->DR;		
	//	USART1->DR = (u8) res;      //测试用，再发回去
		if(USART1_RX_STA<USART1_MAX_RECV_LEN) //还没到最大缓存区的长度，还可以接收数据
			{
				TIM3->CNT=0;         					//Timer3 计数器清空
				if(USART1_RX_STA==0) TIMx_Status(TIM3,ENABLE);	 //0说明刚开始计数,开启定时器，定10ms 
				USART1_RX_BUF[USART1_RX_STA++]=res;		//记录接收到的值		
			}
		else 
			{
			USART1_RX_STA |=1<<15;		 //如果到了定义的最大接收缓存区的长度 强制标记接收完成
			TIMx_Status(TIM3,DISABLE); //关闭定时器
			} 
	
	}
}

// 数据打包、数据解析*******************************************************************8
/*多字节 分解*/
#define BYTE0(dwTemp)       (*(char  *)(&dwTemp))
#define BYTE1(dwTemp)       (*((char *)(&dwTemp) + 1))
#define BYTE2(dwTemp)       (*((char *)(&dwTemp) + 2))
#define BYTE3(dwTemp)       (*((char *)(&dwTemp) + 3))
	
/*变量定义*/
u8 Sendbuf[32] = {0};

/*串口发送以及缓存数据*/
static void usart_buf(uint8_t data, uint8_t i)
{
	Sendbuf[i] = data;
	while((USART1->SR&0X40)==0);	 
	USART1->DR = (u8) data;   
	Delay_us( 6 );
}

/*传感器数据发送*/
void sensor_datasend(void)
{
  u8 sum = 0 ,t=0,i=0;
	usart_buf(0x88,t++); //根据数据帧格式 自定义
	usart_buf(0xA1,t++);
  usart_buf(12, t++);  //发送作为数据的字节数  
/*数据*/	
	// rol
	usart_buf(BYTE3(IMU.Rol.AngularVelocity), t++); usart_buf(BYTE2(IMU.Rol.AngularVelocity), t++);
	usart_buf(BYTE1(IMU.Rol.AngularVelocity), t++); usart_buf(BYTE0(IMU.Rol.AngularVelocity), t++);	
		//2 pit
	usart_buf(BYTE3(IMU.Pit.AngularVelocity), t++); usart_buf(BYTE2(IMU.Pit.AngularVelocity), t++);
	usart_buf(BYTE1(IMU.Pit.AngularVelocity), t++); usart_buf(BYTE0(IMU.Pit.AngularVelocity), t++);	
	 //3 yaw
	usart_buf(BYTE3(IMU.Yaw.AngularVelocity), t++); usart_buf(BYTE2(IMU.Yaw.AngularVelocity), t++);
	usart_buf(BYTE1(IMU.Yaw.AngularVelocity), t++); usart_buf(BYTE0(IMU.Yaw.AngularVelocity), t++);	
	for(i=0; i<t; i++)
    {
		sum += Sendbuf[i];
	  }
	USART1->DR = (u8)sum;//校验和	
}

//数据解析函数

void NIMI_ReciveData(u8 *databuf)
{
  if( *( databuf ) == 0x8A ) //判断帧头
 {
	 if( *( databuf+3 ) == 0XAE){
     /*外环PID参数*/
	#if CONTRO_EX
		 
		 //yaw外环参数  数据还原 数据分析
	   PID[ANGLE_YAW].Kp = ((u16)(*(databuf+4)<<8)|*(databuf+5)) ; 
	   PID[ANGLE_YAW].Ki = ((u16)(*(databuf+6)<<8)|*(databuf+7)) ;
	   PID[ANGLE_YAW].Kd = ((u16)(*(databuf+8)<<8)|*(databuf+9)) ;	
		 /*yaw内环*/
		 PID[RATE_YAW].Kp = ((u16)(*(databuf+10)<<8)|*(databuf+11)) ;
	   PID[RATE_YAW].Ki = ((u16)(*(databuf+12)<<8)|*(databuf+13)) ;
	   PID[RATE_YAW].Kd = ((u16)(*(databuf+14)<<8)|*(databuf+15)) ;
  #else	 		
		 /*内环PID参数*/
		 PID[RATE_ROL].Kp = ((u16)(*(databuf+4)<<8)|*(databuf+5)) ;
	   PID[RATE_ROL].Ki = ((u16)(*(databuf+6)<<8)|*(databuf+7)) ;
	   PID[RATE_ROL].Kd = ((u16)(*(databuf+8)<<8)|*(databuf+9)) ;
	 
		 PID[RATE_PIT].Kp = ((u16)(*(databuf+10)<<8)|*(databuf+11)) ;
	   PID[RATE_PIT].Ki = ((u16)(*(databuf+12)<<8)|*(databuf+13)) ;
	   PID[RATE_PIT].Kd = ((u16)(*(databuf+14)<<8)|*(databuf+15)) ;
		 
		 PID[RATE_YAW].Kp = ((u16)(*(databuf+16)<<8)|*(databuf+17)) ;
	   PID[RATE_YAW].Ki = ((u16)(*(databuf+18)<<8)|*(databuf+19)) ;
	   PID[RATE_YAW].Kd = ((u16)(*(databuf+20)<<8)|*(databuf+21)) ;	
 #endif
	 }
 else if(*(databuf+3)==0xAD){ 
   NIMI_PID_Send();
   }
 }
}
